# -*- coding: utf-8 -*-

# backend/services/chat_service.py
"""
聊天服务 - 核心业务逻辑
"""

from typing import List, Dict, Any, Optional, AsyncGenerator
from langchain.schema import BaseMessage, HumanMessage, AIMessage
from ..graphs.multi_agent_graph import MultiAgentGraph
from ..models import ModelFactory
from .data_service import DataService
import asyncio
import logging
from datetime import datetime
import uuid

logger = logging.getLogger(__name__)

class ChatService:
    """聊天服务类"""
    
    def __init__(self, api_keys: Dict[str, str]):
        self.api_keys = api_keys
        self.multi_agent_graph = MultiAgentGraph(api_keys)
        self.data_service = DataService()
        self.active_conversations: Dict[str, List[BaseMessage]] = {}
    
    async def send_message(
        self, 
        message: str, 
        conversation_id: str,
        selected_models: Optional[List[str]] = None,
        stream: bool = False
    ) -> Dict[str, Any]:
        """发送消息并获取AI响应"""
        try:
            # 获取对话历史
            conversation_history = await self.get_conversation_history(conversation_id)
            
            # 如果指定了特定模型，直接调用
            if selected_models and len(selected_models) == 1:
                return await self._single_model_response(
                    message, conversation_history, selected_models[0], stream
                )
            
            # 使用多智能体工作流
            start_time = datetime.now()
            result = await self.multi_agent_graph.run(message, conversation_history)
            
            # 保存对话记录
            await self._save_conversation_turn(
                conversation_id, 
                message, 
                result["final_response"],
                result["metadata"]
            )
            
            processing_time = (datetime.now() - start_time).total_seconds()
            
            return {
                "response": result["final_response"],
                "selected_models": result["selected_models"],
                "individual_responses": result["individual_responses"],
                "conversation_id": conversation_id,
                "processing_time": processing_time,
                "metadata": result["metadata"]
            }
            
        except Exception as e:
            logger.error(f"消息处理失败: {e}")
            return {
                "response": f"抱歉，处理您的消息时出现错误: {str(e)}",
                "selected_models": [],
                "individual_responses": {},
                "conversation_id": conversation_id,
                "processing_time": 0,
                "metadata": {"error": str(e)}
            }
    
    async def stream_message(
        self, 
        message: str, 
        conversation_id: str,
        model_name: str = "gpt-4"
    ) -> AsyncGenerator[str, None]:
        """流式发送消息"""
        try:
            # 获取对话历史
            conversation_history = await self.get_conversation_history(conversation_id)
            messages = conversation_history + [HumanMessage(content=message)]
            
            # 创建模型实例
            api_key = self._get_api_key_for_model(model_name)
            model = ModelFactory.create_model(model_name, api_key)
            await model.initialize()
            
            # 流式生成响应
            full_response = ""
            async for chunk in model.stream_response(messages):
                full_response += chunk
                yield chunk
            
            # 保存完整响应
            await self._save_conversation_turn(
                conversation_id, 
                message, 
                full_response,
                {"model": model_name, "stream": True}
            )
            
        except Exception as e:
            logger.error(f"流式消息处理失败: {e}")
            yield f"抱歉，处理消息时出现错误: {str(e)}"
    
    async def _single_model_response(
        self, 
        message: str, 
        conversation_history: List[BaseMessage],
        model_name: str,
        stream: bool = False
    ) -> Dict[str, Any]:
        """单模型响应"""
        try:
            api_key = self._get_api_key_for_model(model_name)
            model = ModelFactory.create_model(model_name, api_key)
            await model.initialize()
            
            messages = conversation_history + [HumanMessage(content=message)]
            response = await model.generate_response(messages)
            
            return {
                "response": response.content,
                "selected_models": [model_name],
                "individual_responses": {model_name: response.content},
                "processing_time": 0,
                "metadata": response.metadata
            }
            
        except Exception as e:
            logger.error(f"单模型响应失败: {e}")
            raise
    
    def _get_api_key_for_model(self, model_name: str) -> str:
        """获取模型对应的API密钥"""
        if model_name.startswith("gpt"):
            return self.api_keys.get("openai", "")
        elif model_name.startswith("claude"):
            return self.api_keys.get("anthropic", "")
        elif model_name.startswith("gemini"):
            return self.api_keys.get("google", "")
        elif model_name == "文心一言":
            return self.api_keys.get("baidu", "")
        elif model_name == "通义千问":
            return self.api_keys.get("aliyun", "")
        elif model_name == "豆包":
            return self.api_keys.get("bytedance", "")
        else:
            raise ValueError(f"未知模型类型: {model_name}")
    
    async def get_conversation_history(self, conversation_id: str) -> List[BaseMessage]:
        """获取对话历史"""
        try:
            if conversation_id in self.active_conversations:
                return self.active_conversations[conversation_id]
            
            # 从数据库加载
            history = await self.data_service.load_conversation(conversation_id)
            messages = []
            
            for record in history:
                if record["role"] == "user":
                    messages.append(HumanMessage(content=record["content"]))
                elif record["role"] == "assistant":
                    messages.append(AIMessage(content=record["content"]))
            
            self.active_conversations[conversation_id] = messages
            return messages
            
        except Exception as e:
            logger.error(f"加载对话历史失败: {e}")
            return []
    
    async def _save_conversation_turn(
        self, 
        conversation_id: str, 
        user_message: str, 
        ai_response: str,
        metadata: Dict[str, Any]
    ):
        """保存对话轮次"""
        try:
            # 保存到内存
            if conversation_id not in self.active_conversations:
                self.active_conversations[conversation_id] = []
            
            self.active_conversations[conversation_id].extend([
                HumanMessage(content=user_message),
                AIMessage(content=ai_response)
            ])
            
            # 保存到数据库
            await self.data_service.save_message(
                conversation_id, "user", user_message, metadata
            )
            await self.data_service.save_message(
                conversation_id, "assistant", ai_response, metadata
            )
            
        except Exception as e:
            logger.error(f"保存对话失败: {e}")
    
    async def create_conversation(self, title: str = None) -> str:
        """创建新对话"""
        conversation_id = str(uuid.uuid4())
        await self.data_service.create_conversation(
            conversation_id, 
            title or f"对话 {datetime.now().strftime('%Y-%m-%d %H:%M')}"
        )
        return conversation_id
    
    async def list_conversations(self) -> List[Dict[str, Any]]:
        """列出所有对话"""
        return await self.data_service.list_conversations()
    
    async def delete_conversation(self, conversation_id: str) -> bool:
        """删除对话"""
        try:
            success = await self.data_service.delete_conversation(conversation_id)
            if success and conversation_id in self.active_conversations:
                del self.active_conversations[conversation_id]
            return success
        except Exception as e:
            logger.error(f"删除对话失败: {e}")
            return False
